/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dljk.core;

import java.awt.Graphics;
import java.awt.LayoutManager;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JPanel;

/**
 *
 * @author Ariman
 */
public class GamePanel extends JPanel {

    public GamePanel(LayoutManager layout) {
        super(layout);
        initData();
    }

    public GamePanel() {
        initData();
    }

    @Override
    public void paintComponent(Graphics g) {
        m_backRenderer.renderBackground(getWidth(), getHeight(), g);
        for (BoardField bf : BoardField.values()) {
            Deck deck = klondikeEngine.getKlondikeCardSet().get(bf);
            for (GameCard gc : klondikeEngine.getKlondikeCardSet().get(bf)) {
                m_cardRenderer.renderCard(getCardX(bf, (Deck) deck.clone(), deck.indexOf(gc)), getCardY(bf, (Deck) deck.clone(), deck.indexOf(gc)), g, gc);
            }
        }
    }

    private void initData() {
        m_thisPanel = this;
        klondikeEngine = new KlondikeEngine();
        try {
            m_cardRenderer = new CardRenderer("defaultCardSet");
            m_backRenderer = new BGRenderer();

        } catch (IOException ex) {
            Logger.getLogger(GamePanel.class.getName()).log(Level.SEVERE, null, ex);
        }
        this.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent evt) {
                if (evt.getButton() != MouseEvent.BUTTON1) {
                    return;
                }
                int mouseX = evt.getPoint().x;
                int mouseY = evt.getPoint().y;
                Pair pair = m_thisPanel.ClickedCard(mouseX, mouseY);
                klondikeEngine.OnFieldClicked(pair);
                repaint(); 
            }
        });

    }

    private Pair ClickedCard(int mouseX, int mouseY) {
        BoardField bfOut = null;
        boolean flag = false;
        int number = 0;
        int numberOut = -1;
        for (BoardField bf : BoardField.values()) {
            switch (bf) {
                case BF_CLOSED_CARDS:
                case BF_OPEN_CARDS:
                case BF_FINISH_1:
                case BF_FINISH_2:
                case BF_FINISH_3:
                case BF_FINISH_4:
                    if ((mouseX >= getPanelX(bf)) && (mouseX <= getPanelX(bf) + CardRenderer.iCARD_WIDTH)) {
                        if ((mouseY >= getPanelY(bf)) && (mouseY <= getPanelY(bf) + CardRenderer.iCARD_HEIGHT)) {
                            bfOut = bf;
                            numberOut = klondikeEngine.getKlondikeCardSet().get(bfOut).size()-1;
                            flag = false;                            
                        }
                    }
                    break;
                case BF_GAMEZONE_1:
                case BF_GAMEZONE_2:
                case BF_GAMEZONE_3:
                case BF_GAMEZONE_4:
                case BF_GAMEZONE_5:
                case BF_GAMEZONE_6:
                case BF_GAMEZONE_7:
                    if ((mouseX >= getPanelX(bf)) && (mouseX <= getPanelX(bf) + CardRenderer.iCARD_WIDTH)) {
                        if (mouseY >= getPanelY(bf)) {
                            bfOut = bf;
                            flag = true;
                        }
                    }
                    break;
            }
            if (flag) {
                Deck deck = klondikeEngine.getKlondikeCardSet().get(bfOut);
                int fromY = getPanelY(bfOut);
                int toY = fromY;
                for (GameCard gc : deck) {
                    if (!gc.getFace()) {
                        if (deck.indexOf(gc) == (deck.size() - 1)) {
                            toY += CardRenderer.iCARD_HEIGHT;
                        } else {
                            toY += iOFFSET_Y / 6;
                        }
                    } else {
                        if (deck.indexOf(gc) == (deck.size() - 1)) {
                            toY += CardRenderer.iCARD_HEIGHT;
                        } else {
                            toY += iOFFSET_Y;
                        }
                    }

                    if ((mouseY >= fromY) && (mouseY <= toY)) {
                        flag = false;
                        numberOut = number;
                        number = 0;
                        break;
                    } else {
                        fromY = toY;
                        number++;
                    }
                }
            }
        }
        return new Pair(bfOut, numberOut);
    }

    public static int getPanelX(BoardField field) {
        int retX = iBASE_X;
        switch (field) {
            case BF_CLOSED_CARDS:
                retX = iBASE_X;
                break;
            case BF_OPEN_CARDS:
                retX = iBASE_X + iOFFSET_X + CardRenderer.iCARD_WIDTH;
                break;
            case BF_FINISH_1:
                retX = iBASE_X + iOFFSET_X * 4 + CardRenderer.iCARD_WIDTH * 4;
                break;
            case BF_FINISH_2:
                retX = iBASE_X + iOFFSET_X * 5 + CardRenderer.iCARD_WIDTH * 5;
                break;
            case BF_FINISH_3:
                retX = iBASE_X + iOFFSET_X * 6 + CardRenderer.iCARD_WIDTH * 6;
                break;
            case BF_FINISH_4:
                retX = iBASE_X + iOFFSET_X * 7 + CardRenderer.iCARD_WIDTH * 7;
                break;
            case BF_GAMEZONE_1:
                retX = iBASE_X + iOFFSET_X * 2 + iOFFSET_X * 0 + CardRenderer.iCARD_WIDTH * 0 + CardRenderer.iCARD_WIDTH / 2;
                break;
            case BF_GAMEZONE_2:
                retX = iBASE_X + iOFFSET_X * 2 + iOFFSET_X * 1 + CardRenderer.iCARD_WIDTH * 1 + CardRenderer.iCARD_WIDTH / 2;
                break;
            case BF_GAMEZONE_3:
                retX = iBASE_X + iOFFSET_X * 2 + iOFFSET_X * 2 + CardRenderer.iCARD_WIDTH * 2 + CardRenderer.iCARD_WIDTH / 2;
                break;
            case BF_GAMEZONE_4:
                retX = iBASE_X + iOFFSET_X * 2 + iOFFSET_X * 3 + CardRenderer.iCARD_WIDTH * 3 + CardRenderer.iCARD_WIDTH / 2;
                break;
            case BF_GAMEZONE_5:
                retX = iBASE_X + iOFFSET_X * 2 + iOFFSET_X * 4 + CardRenderer.iCARD_WIDTH * 4 + CardRenderer.iCARD_WIDTH / 2;
                break;
            case BF_GAMEZONE_6:
                retX = iBASE_X + iOFFSET_X * 2 + iOFFSET_X * 5 + CardRenderer.iCARD_WIDTH * 5 + CardRenderer.iCARD_WIDTH / 2;
                break;
            case BF_GAMEZONE_7:
                retX = iBASE_X + iOFFSET_X * 2 + iOFFSET_X * 6 + CardRenderer.iCARD_WIDTH * 6 + CardRenderer.iCARD_WIDTH / 2;
                break;
        }
        return retX;
    }

    public static int getPanelY(BoardField field) {
        int retY = iBASE_Y;
        switch (field) {
            case BF_CLOSED_CARDS:
            case BF_OPEN_CARDS:
            case BF_FINISH_1:
            case BF_FINISH_2:
            case BF_FINISH_3:
            case BF_FINISH_4:
                retY = iBASE_Y;
                break;
            case BF_GAMEZONE_1:
            case BF_GAMEZONE_2:
            case BF_GAMEZONE_3:
            case BF_GAMEZONE_4:
            case BF_GAMEZONE_5:
            case BF_GAMEZONE_6:
            case BF_GAMEZONE_7:
                retY = iBASE_Y + iOFFSET_Y + CardRenderer.iCARD_HEIGHT;
                break;
        }
        return retY;
    }

    private int getCardX(BoardField field, Deck deck, int num) {
        return getPanelX(field);
    }

    private int getCardY(BoardField field, Deck deck, int num) {
        int base = getPanelY(field);
        switch (field) {
            case BF_GAMEZONE_1:
            case BF_GAMEZONE_2:
            case BF_GAMEZONE_3:
            case BF_GAMEZONE_4:
            case BF_GAMEZONE_5:
            case BF_GAMEZONE_6:
            case BF_GAMEZONE_7:
                for (int i = 0; i < num; i++) {
                    if (deck.removeBottom().getFace()) {
                        base += iOFFSET_Y;
                    } else {
                        base += iOFFSET_Y / 6;
                    }
                }
                break;
        }
        return base;
    }
    public static final int iBASE_X = 15;
    public static final int iBASE_Y = 15;
    public static final int iOFFSET_X = 10;
    public static final int iOFFSET_Y = 30;
    // отрисовщик фона
    private BGRenderer m_backRenderer = null;
    // отрисовщик карт
    private CardRenderer m_cardRenderer = null;
    private KlondikeEngine klondikeEngine;
    private GamePanel m_thisPanel;
}
